package controller

import (
	"errors"
	"fmt"
	"ordersystem/config"
	"ordersystem/model"
	"ordersystem/util"
	"strconv"
	"time"

	"github.com/gofiber/fiber/v2"
)

type PageParam struct {
	Page int `json:"page" xml:"page" form:"page"`
}

/*
	@params
	username, password and rememberMe
	in json formation
*/

func UserLoginController(ctx *fiber.Ctx) error {

	type BodyParams struct {
		Username   string `json:"username"`
		Password   string `json:"password"`
		RememberMe bool   `json:"rememberMe"`
	}

	var bodyParms BodyParams

	ctx.BodyParser(&bodyParms)

	if bodyParms.Username == "" || bodyParms.Password == "" {
		return errors.New(config.REQUEST_DATAFORMATION_ERROR)
	}

	var user model.User

	user.Telphone = bodyParms.Username
	user.Password = bodyParms.Password

	if user.QueryUserByPassword(); user.Id == 0 {
		return errors.New(config.REQUEST_USERNAME_OR_PASSWORD_ERROR)
	}

	result := make(map[string]interface{})

	result["telphone"] = user.Telphone
	result["id"] = user.Id
	result["name"] = user.Name
	result["identify"] = user.Identify
	now := time.Now().Add(time.Hour * 24 * 7).Unix()
	result["expirestime"] = now
	result["creator"] = user.Creator

	originData := strconv.Itoa(int(user.Id)) + strconv.Itoa(int(user.Identify)) + user.Telphone + strconv.Itoa(int(user.Creator)) + strconv.FormatInt(now, 10)
	fmt.Println(originData)
	token := util.DoubleMd5Salt(originData)

	result["token"] = token
	util.SendResponse(ctx, result)
	return nil
}

func UserQueryUserController(ctx *fiber.Ctx) error {
	var user model.User
	ctx.BodyParser(&user)
	if user.Id == 0 {
		data, _ := strconv.Atoi(ctx.Cookies("Id"))
		user.Id = int32(data)
		//identify := ctx.Cookie("identify","")
		// if identify == "2"{
		// 	return errors.New(config.REQUEST_UNAUTHORIZATION_ERROR)
		// }else if identify == "1"{
		// 	user.CreateUser()
		// }
	}
	if er := user.QueryUser(); er != nil {
		return er
	}
	util.SendResponse(ctx, user)
	return nil
}

func UserQueryUsersController(ctx *fiber.Ctx) error {
	var page PageParam
	ctx.BodyParser(&page)

	result := util.GetCookieForMap(ctx)

	var params int32
	if result["identify"] == int32(0) {
		params = 0
	} else {
		params = result["id"].(int32)
	}

	results, err := model.QueryUsersForAdminOrSuperAdmin(page.Page-1, params)
	if err != nil {
		return err
	}
	util.SendResponse(ctx, results)
	return nil
}

func UserUpdateUserController(ctx *fiber.Ctx) error {
	var user model.User
	ctx.BodyParser(&user)
	cookie := util.GetCookieForMap(ctx)

	if cookie["id"] == user.Id || ctx.Cookies("identify") == "0" {
		if err := user.UpdateUser(); err != nil {
			fmt.Println(err)
			return err
		}
		util.SendResponse(ctx, nil)
		return nil
	}

	if ctx.Cookies("identify") == "2" {
		return errors.New(config.REQUEST_UNAUTHORIZATION_ERROR)
	}

	var originUser model.User
	originUser.Id = user.Id

	if err := originUser.QueryUser(); err != nil {
		return err
	}

	if originUser.Identify < 2 {
		return errors.New(config.REQUEST_UNAUTHORIZATION_ERROR)
	}

	if err := user.UpdateUser(); err != nil {
		return err
	}
	util.SendResponse(ctx, nil)

	return nil
}

func UserDeleteUserController(ctx *fiber.Ctx) error {
	var user model.User
	ctx.BodyParser(&user)

	// Delete the user from the superadmin or himself!

	requestUserId, err := strconv.Atoi(ctx.Cookies("id"))

	if err != nil {
		return err
	}

	if int32(requestUserId) == user.Id || ctx.Cookies("identify") == "0" {
		if err := user.DeleteUser(); err != nil {
			return err
		}
		util.SendResponse(ctx, nil)
		return nil
	}

	// Don't permit user to delete other user or admin or superadmin!

	if ctx.Cookies("identify") == "2" {
		return errors.New(config.REQUEST_UNAUTHORIZATION_ERROR)
	}

	// I need to check origin user data to see if the user is createBy this admin

	var originUser model.User
	originUser.Id = user.Id

	if err := originUser.QueryUser(); err != nil {
		return err
	}

	if originUser.Identify < 2 || originUser.Creator != int32(requestUserId) {
		return errors.New(config.REQUEST_UNAUTHORIZATION_ERROR)
	}

	if err := user.DeleteUser(); err != nil {
		return err
	}
	util.SendResponse(ctx, nil)

	return nil
}

func UserCreateUserController(ctx *fiber.Ctx) error {
	var user model.User
	ctx.BodyParser(&user)
	data, _ := strconv.Atoi(ctx.Cookies("id"))
	user.Creator = int32(data)

	data, _ = strconv.Atoi(ctx.Cookies("identify"))

	if data == 2 || (data == 1 && user.Identify != 2) {
		return errors.New(config.REQUEST_UNAUTHORIZATION_ERROR)
	}

	if err := user.CreateUser(); err != nil {
		return err
	}

	util.SendResponse(ctx, nil)
	return nil
}

func UserQueryNumberController(ctx *fiber.Ctx) error {

	result := util.GetCookieForMap(ctx)

	var params int32

	if result["identify"] == int32(0) {
		params = 0
	} else {
		params = result["id"].(int32)
	}

	if number, err := model.QueryUserNumber(params); err != nil {
		return err
	} else {
		util.SendResponse(ctx, number)
		return nil
	}
}
